<script setup lang="ts">
import {defineProps,ref,Ref,watch, toRaw, onMounted ,reactive} from 'vue'
// import axios from 'axios'
import { fabric }  from 'fabric'

//const props =defineProps<{ msg: (fabric.Rect|fabric.Text)[] }>()
const props =defineProps<{ msg: fabric.Object[] }>()

watch(
  () => props.msg,
  (newVal, oldVal) => {
    console.log('监听基本类型数据testStr')
    console.log('new', newVal)
    console.log('old', oldVal)
  }
)
const domCanvas: Ref<HTMLCanvasElement | null> = ref(null);
const canvas = ref<fabric.Canvas>();
//const circle = ref<fabric.Circle>();

onMounted(() => {
    init();
    draw();
});

const show_font   = ref(false)
const show_color = ref(false)
const show_zoom = ref(false)
const font_size = ref(0)
const canvas_zoom = ref(0)
const font_color = ref('red')

function showFonts(){
  let fontSize = getCanvasAttr('fontSize')
  font_size.value = parseInt(fontSize)
  show_font.value = true
}
function showZooms(){
  let zoom = canvas.value?.getZoom()
  canvas_zoom.value = parseInt(''+zoom) * 30
  show_zoom.value = true
}
function showColors(){
  show_color.value = true
}
function onChangeSize(val:any){
   setCanvasAttr({fontSize:val})
}
function onChangeZoom(val:any){
    console.log(val)
    let zoom = parseInt(''+val) /30
    canvas.value?.setZoom(zoom)
    canvas.value?.renderAll()

}
let move = {
   isDragging:false,
   lastPosX:0,lastPosY:0,startX:0,startY:0,
}
const is_move=ref(false)
function setMove(){
  if(!is_move.value){
    is_move.value = true; move.isDragging = true;
  }else{
    is_move.value = false; move.isDragging = false;
  }
}

function init() {
   let fibcanvas = new fabric.Canvas(domCanvas.value, {
      width: 500, height: 500,
      backgroundColor: "#a3fd00",
   });
    function convertE(e:any){
        let type = e.type
        if(type=='mousemove'){
           return e
        }else{
           e.clientX  = e.changedTouches[0].clientX
           e.clientY  = e.changedTouches[0].clientY
           return e
        }
    }
    fibcanvas.on('mouse:down', (opt) =>{
      var evt = convertE(opt.e);
      console.log('down')
      console.log(evt)
      if (move.isDragging) {
        fibcanvas.selection = false
        move.lastPosX = evt.clientX
        move.lastPosY = evt.clientY
        move.startX = evt.clientX
        move.startY  = evt.clientY
      }
    })
    fibcanvas.on('mouse:move', (opt)=> {
      if (move.isDragging) {
        var e = convertE(opt.e);
        var vpt = fibcanvas.viewportTransform;
        //@ts-ignore
        vpt[4] += e.clientX - move.lastPosX;   vpt[5] += e.clientY - move.lastPosY
        move.lastPosX = e.clientX
        move.lastPosY = e.clientY
        fibcanvas.requestRenderAll()
        //console.log(move)
      }
    })
    fibcanvas.on('gesturestart',()=>{
      console.log('DDDDD')
    })
    fibcanvas.on('mouse:up', (opt)=> {
      // on mouse up we want to recalculate new interaction
      // for all objects, so we call setViewportTransform
      var e = convertE(opt.e);
      let transform = fibcanvas.viewportTransform
      if(transform){
         fibcanvas.setViewportTransform(transform)
         fibcanvas.selection = true
      }
      fibcanvas.renderAll()
    })
    canvas.value= fibcanvas
 }

function draw() {
    for(var i in props.msg){
        let obj = props.msg[i]
        obj.on('selected',(ievent:any)=>{
            // let event = ievent.e
            let target = ievent.target
            console.log('selected')
            console.log(target)
        })
        obj.on('deselected',(ievent:any)=>{
            // let event = ievent.e
            let target = ievent.target
            console.log(target)
            let json = canvas.value?.toJSON()
            console.log(json)
        })
        toRaw(canvas.value)?.add(obj);
        toRaw(canvas.value)?.setActiveObject(obj);
   }
}

function getCanvasAttr(attr:string){
   let selecteds = canvas.value?.getActiveObjects()
   if(selecteds && selecteds.length > 0){
     //@ts-ignore
     return selecteds[0][attr] || ''
   }
   return '';
}

function setCanvasAttr(attrs:any){
   let selecteds = toRaw(canvas.value)?.getActiveObjects()
   if(selecteds && selecteds.length > 0){
      selecteds.forEach((obj)=>{
        for(var k in attrs){
            let value = attrs[k]
            //@ts-ignore
            toRaw(obj)[k] = value;toRaw(obj)['dirty'] = true
        }
        console.log(obj)
      })

      toRaw(canvas.value)?.renderAll()
      console.log(toRaw(canvas.value))
   }
}
const colors=ref(['red','blue','green','orange','purple','black','white'])
function setColor(index:any){
  let color = colors.value[index]
  console.log(color)
  setCanvasAttr({fill:color})
}
</script>

<template>
    <canvas ref="domCanvas"></canvas>
    <div class="buttons">
        <div :class="'button '+(is_move?'move':'')" @click="setMove">移动</div>
        <div class="button" @click="showFonts">字体</div>
        <div class="button" @click="showZooms">缩放</div>
        <div class="button" @click="showColors">颜色</div>
    </div>

    <van-popup v-model:show="show_font" round position="bottom">
        <div class="container">
            <div class="label">字体大小</div>
            <van-slider class="slider" v-model="font_size" @change="onChangeSize" />
        </div>
    </van-popup>

    <van-popup v-model:show="show_zoom" round position="bottom">
        <div class="container">
            <div class="label">缩放大小</div>
            <van-slider :min="5" :max="50" class="slider" v-model="canvas_zoom" @change="onChangeZoom" />
        </div>
    </van-popup>

    <van-popup v-model:show="show_color" round position="bottom">
        <van-grid :column-num="7">
          <van-grid-item v-for="(color,index) in colors" >
              <div @click="setColor(index)" :style="'background:'+color" class="color-item"></div>
          </van-grid-item>
        </van-grid>
    </van-popup>

</template>

<style scoped>
.slider{
  margin:30px;
}
.color-item{
    height: 40px;
    width:100%;
}
.buttons{
  display:flex;
  justify-content: space-between;
  padding:8px;
}
.button.move{
  color:red;
}
.container{
    display: flex;
    align-items: baseline;
}
.container .label{
    width:120px;
}
</style>
